<?php

namespace app\factory;

use app\model\activity\ActivityGoodsModel;
use app\model\agency\AgencyGoodsModel;
use app\model\goods\GoodsAttributeModel;
use app\model\goods\GoodsCommonModel;
use app\model\goods\GoodsFreightModel;
use app\model\goods\GoodsModel;
use app\model\order\OrderItemModel;
use app\model\order\OrderItemOutModel;
use app\model\order\OrderModel;
use app\model\store\StoreModel;
use app\model\system\SysConfigModel;
use app\model\user\UserAddressModel;
use app\model\user\UserCollectUpModel;
use app\model\user\UserCouponModel;
use app\model\user\UserModel;

/**
 * 订单
 * Class Order
 * @package app\factory
 */
class Order
{
    /**
     * 待生成订单 数据展示
     * @param $formData
     * @param $userInfo
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function orderInfo($formData, $userInfo)
    {
        $benefit = 0;//需要缴纳基金
        $goods_temp = [];
        $goods = [];
        switch ($formData['showType']) {
            case "goods_order":
            case "bean_order":
                $goods_info = $formData['goods_info'];
                $goods_info_arr = json_decode($goods_info, true);
                $goods_temp = $this->_getGoodsItem($goods_info_arr, '', $userInfo['user_id']);
                if ($goods_temp['code'] == 1) {
                    $goods['list'] = $goods_temp['data'];
                } else {
                    return $goods_temp;
                }
                break;
            default:
                break;
        }
        if (empty($goods_temp)) {
            $rsps['code'] = 0;
            $rsps['msg'] = "商品信息有误";
            return $rsps;
        }
        $goods['fund'] = $benefit;
        $goods['freight'] = $goods_temp['goods_freight'];//运费
        $goods['count_goods_price'] = $goods_temp['count_goods_price'];//总购买价
        $goods['count_return_money'] = $goods_temp['count_return_money'];//总返现
        $goods['count_goods_price'] += $goods['freight'];
        $goods['count_goods_price'] += $benefit;
        $goods['count_return_money'] = round($goods['count_return_money'], 2);
        $goods['count_goods_price'] = round($goods['count_goods_price'], 2);
        $UserAddressModel = new UserAddressModel();
        $address = $UserAddressModel
            ->where("user_id", $userInfo['user_id'])
            ->order("is_default asc,id desc")
            ->field("id,take_phone,take_name,province,city,district,detail_address,is_default")
            ->find();//用户地址
        $rsps['data'] = $goods;
        $rsps['data']['bean'] = UserModel::getBean($userInfo['user_id']);
        $rsps['data']['userAddress'] = $address;
        $couponList = UserCouponModel::getCouponList($userInfo['user_id'], $goods['count_goods_price']);
        $rsps['data']['couponList'] = $couponList;
        $rsps['code'] = 1;
        return $rsps;
    }

    /**
     * 订单统一下单接口
     * @param $formData
     * $formData['address_id'] 地址id
     * $formData['buy_msg'] 订单留言备注
     * $formData['goods_id'] 商品id  多商品 逗号隔开
     * $formData['goods_number'] 普通商品数量  多商品 逗号隔开（与商品id对应）
     * $formData['coupon_id']  商品兑换券id
     * $formData['showType'] 是否拼团 goods_order 正常订单  bead_order 趣豆商城订单
     * $formData['bean'] 消耗的趣豆
     * @param $userInfo
     * @return array|mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function cearteOrder($formData, $userInfo)
    {
        $goods_info_temp = $formData['goods_info'];
        $goods_info_arr_temp = json_decode($goods_info_temp, true);
        $goods_common_model = new GoodsCommonModel();
        foreach ($goods_info_arr_temp as $value) {
            $num = OrderItemModel::getBuyNumber($value['goods_id'], $value['attribute_ids'], $userInfo['user_id']);
            $goods_common = $goods_common_model->getCommonGoods($value['goods_id'], $value['attribute_ids'], true);
            if (empty($goods_common)) {
                throw new \think\Exception("商品不存在或库存不足", 0);
            }
            if (intval($goods_common[0]['goods_limit']) > 0) {
                if (intval($goods_common[0]['goods_limit']) <= $num || (intval($goods_common[0]['goods_limit']) - $num) < $value['goods_number']) {
                    throw new \think\Exception("超出商品限购数量，不能购买", 0);
                }
            }
        }

        $user_model = new UserModel();
        $user_temp = $user_model->getInfo($userInfo['user_id'], "id,agency_id,phone,top_user_id,nick_name,head_img,member_level,member_date");
        $top_code = $formData['top_code'];
        $channel = 0;
        if (!empty($top_code)) {
            $channel = $user_model->getMemberId($top_code);
        }
        $UserAddressModel = new UserAddressModel();
        $map = [
            'id' => $formData['address_id'],
            'user_id' => $userInfo['user_id'],
        ];
        $address = $UserAddressModel->where($map)->find();//用户下单地址
        if (!isset($address['id'])) {
            throw new \think\Exception("地址不存在", 0);
        }
        $lng = 0;
        $lat = 0;
        if (!empty($user_temp['member_level'])) {
            if ($user_temp['member_date'] < time()) {
                $user_temp['member_level'] = 0;
            }
        }
        $agency_id = $user_temp['agency_id'];
        $top_top_user_id = 0;
        $top_user_id = $user_temp['top_user_id'];
        if (!empty($top_user_id)) {
            $user_top_temp = $user_model->getInfo($top_user_id, "id,top_user_id");
            if (UserModel::isVipMember($user_top_temp['top_user_id'])) {
                $top_top_user_id = $user_top_temp['top_user_id'];
            }
        }
        if (!UserModel::isVipMember($user_temp['top_user_id'])) {
            $top_user_id = 0;
        }
        if (!UserModel::isVipMember($top_top_user_id)) {
            $top_top_user_id = 0;
        }

        $detail_address = $address['province'] . " " . $address['city'] . " " . $address['district'] . " " . $address['detail_address'];//收货地址;
//        $detail_address = "收货地址";//收货地址;
        $take_mode = isset($formData['take_mode']) ? $formData['take_mode'] : 'logistics';//类型 logistics物流、take自取
        $take_time = 0;
        $reserved_phone = "";
        if ($take_mode == 'take') {
            $take_time = $formData['take_time'] / 1000; //自取时间（时间戳毫秒）
            $address['take_phone'] = $formData['reserved_phone'];//预留电话
        }
        $user_data = [
            'agency_id' => $agency_id,
            'top_user_id' => $top_user_id,
            'top_top_user_id' => $top_top_user_id,
            'order_lng' => $lng,
            'order_lat' => $lat,
            'user_id' => $userInfo['user_id'],
            'nick_name' => $user_temp['nick_name'],
            'head_img' => $user_temp['head_img'],
            'member_level' => $user_temp['member_level'],
            'take_mode' => $take_mode,
            'take_address' => $detail_address,
            'take_name' => $user_temp['nick_name'],
            'take_phone' => $user_temp['phone'],
            'take_time' => $take_time,
            'reserved_phone' => $reserved_phone,
            'buy_msg' => $formData['buy_msg'],
            'bean' => $formData['bean'],
            'discounts' => $formData['discounts'],
            'coupon_id' => $formData['couponId']
        ];
        $goods_type = 0;
        if ($formData['bean'] == 'bean') {
            $goods_type = 2;
        }
        if ($formData['bean'] == 'gift') {
            $goods_type = 3;
        }
//        $showType = $formData['showType'];//bead_order正常订单
        //锁-高并发
        $file = fopen(__DIR__ . '/lock/order.txt', 'w+');
        //加锁
        if (flock($file, LOCK_EX | LOCK_NB)) {
            //TODO 执行业务代码
            $order_model = new OrderModel();
            $goods_info = $formData['goods_info'];
            $goods_info_arr = json_decode($goods_info, true);
            $goods_temp = $this->_getGoodsItem($goods_info_arr, $channel, $userInfo['user_id'], $user_temp['member_level']);
            if ($goods_temp['code'] == 1) {
                $goods_list = $goods_temp['data'];
                $order_ids = [];
                foreach ($goods_list as $value) {
                    //普通商品订单
                    $basic = $value['basic'];
                    if ($take_mode == 'take') {
                        $basic['goods_freight'] = 0;
                    }
                    $store = $value['store'];
                    if (intval($goods_type) == 3) {
                        if (floatval($formData['discounts']) > 6) {
                            $formData['discounts'] = 0;
                        }
                        $basic['total'] = $basic['total'] - floatval($formData['discounts']);
                    }
                    $rsps = $order_model->addOrder($value['list'], $user_data, $basic['total'], $basic['cost_price'], $channel, $basic['keyword'], $basic['goods_freight'], $store['id'], $goods_type);
                    $order_ids[] = $rsps['data']['order_id'];
                }
                sort($order_ids);
                $rsps['data']['order_id'] = implode('_', $order_ids);
            } else {
                //普通商品订单
                $rsps = $goods_temp;
            }
            flock($file, LOCK_UN);//解锁
        } else {
            $rsps['code'] = 0;
            $rsps['msg'] = "系统繁忙,请重试";
        }
        //关闭文件
        fclose($file);
        return $rsps;
    }

    /**
     * 审核退款
     * @param $order_id
     * @param $out_handle_status
     * @param $out_not_text
     * @param $store_id
     * @return mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function outHandleStatus($order_id, $out_handle_status, $out_not_text, $store_id = 0)
    {
        $order_item_out_model = new OrderItemOutModel();
        $rsps = $order_item_out_model->handleStatus($order_id, $out_handle_status, $out_not_text, 'system', $store_id);
        return $rsps;
    }

    /**
     * 普通商品项处理
     * @param array $goods_info_arr
     * @param int $channel
     * @param int $user_id
     * @param int $member_level 会员等级
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function _getGoodsItem($goods_info_arr = [], $channel = 0, $user_id = 0, $member_level = 1)
    {
        $agency_id = UserModel::getAgencyId($user_id);
        $goods_common_model = new GoodsCommonModel();
        $goods_attribute_ids = [];
        $goods_id_number = [];
        $goods_ids = [];
        foreach ($goods_info_arr as $value) {
            $goods_id_number[$value['goods_id'] . "_" . $value['attribute_ids']] = $value['goods_number'];
            $goods_attribute_ids[] = $value['attribute_ids'];
            $goods_ids[] = $value['goods_id'];
        }
        $field = "a.*,g.goods_title,g.goods_img,g.goods_photo,g.distributor_id,g.store_id,g.goods_special,g.freight_id,g.goods_return_agency_money,g.goods_return_money,g.goods_top_money,g.goods_top_top_money";
        if (count($goods_attribute_ids) > 1) {
            $goods_common_list = $goods_common_model->getCommonAttrIdIn(implode(",", $goods_attribute_ids), $field);
            if (empty($goods_common_list)) {
                $rsps['code'] = 0;
                $rsps['msg'] = "商品不存在";
                return $rsps;
            }
            $goods_list = [];
            $store_model = new StoreModel();
            foreach ($goods_common_list as $value) {
                $goods_list[$value['store_id']][] = $value;
            }
            $goods_data = [];
            $count_goods_price_all = 0;//总购买价
            $count_return_money_all = 0;//总返现
            $total_all = 0;
            $goods_freight_all = 0;
            foreach ($goods_list as $key => $value) {
                $base_freight = 0;
                $total = 0;
                $cost_price = 0;
                $goods_freight = 0;
                $keyword = "";
                $count_goods_price = 0;//总购买价
                $count_return_money = 0;//总返现
                $store = $store_model->getStoreInfo($key, 'id,store_name,store_label');
                $store_arr['store'] = $store;//店铺信息
                $store_arr['list'] = []; //商品列表
                foreach ($value as $goods) {
                    $goods_number = intval($goods_id_number[$goods['goods_id'] . "_" . $goods['attribute_ids']]);
                    if ($goods_number > intval($goods['goods_storage'])) {
                        $goods_storage = AgencyGoodsModel::getStore($agency_id, $goods['goods_id'], $goods['attribute_ids']);
                        if ($goods_number > intval($goods_storage)) {
                            $rsps['code'] = 0;
                            $rsps['data'] = $goods['id'];
                            $rsps['msg'] = "商品库存不足";
                            return $rsps;
                        } else {
                            $goods['goods_storage'] = $goods_storage;
                        }
                    }
                    if ($member_level == 0) {
                        $goods['goods_return_money'] = 0;
                    }
                    $one_freight = 0;
                    $freight_data = GoodsFreightModel::getFreight($goods['freight_id']);
                    if (floatval($freight_data['base_freight']) >= 0) {
                        $base_freight = $freight_data['base_freight'];
                        $one_freight = $freight_data['one_freight'];
                    }
                    //利润
                    $profit = floatval($goods['goods_sell_price']) - floatval($goods['goods_cost_price']);
                    $cost_price += floatval($goods['goods_cost_price']) * intval($goods_number);
                    $store_arr['list'][] = [
                        'goods_id' => $goods['goods_id'],
                        'goods_title' => $goods['goods_title'],
                        'attribute_names' => $goods['attribute_names'],
                        'attribute_ids' => $goods['attribute_ids'],
                        'distributor_id' => $goods['distributor_id'],
                        'attribute_ids_show' => strpos($goods['attribute_ids'], '_') > 0,
                        'goods_img' => $goods['goods_img'],
                        'goods_photo' => $goods['goods_photo'],
                        'goods_special' => $goods['goods_special'],
                        'platform_price' => $goods['goods_sell_price'],
                        'cost_price' => $goods['goods_cost_price'],
                        'goods_price' => $goods['goods_sell_price'],
                        'agency_price' => $goods['goods_agency_price'],
                        'agency_money' => $goods['goods_return_agency_money'] * $profit,
                        'return_money' => $goods['goods_return_money'] * $profit,
                        'agency_profit_money' => floatval($goods['goods_sell_price']) - floatval($goods['goods_agency_price']),
                        'top_money' => $goods['goods_top_money'] * $profit,
                        'top_top_money' => $goods['goods_top_top_money'] * $profit,
                        'channel_money' => $goods['goods_ratio_price'],
                        'goods_storage' => $goods['goods_storage'],
                        'goods_number' => $goods_number,
                        'channel' => $channel
                    ];
                    $goods_freight += ($goods_number - 1) * floatval($one_freight);
                    $total += floatval($goods['goods_sell_price']) * $goods_number;
                    $keyword .= $goods['goods_title'] . "|";
                    $count_return_money += floatval($goods['goods_return_money']) * $goods_number;
                    $count_goods_price += floatval($goods['goods_sell_price']) * $goods_number;
                }
                if ($goods_freight >= 0) {
                    $goods_freight += $base_freight;
                }
                $store_arr['basic'] = [
                    'goods_freight' => $goods_freight,
                    'total' => $total,
                    'cost_price' => $cost_price,
                    'keyword' => $keyword,
                    'count_return_money' => $count_return_money,
                    'count_goods_price' => $count_goods_price,
                ];
                $goods_data[$key] = $store_arr;
                $count_goods_price_all += $count_goods_price;
                $count_return_money_all += $count_return_money;
                $total_all += $total;
                $goods_freight_all += $goods_freight;
            }

            $rsps['code'] = 1;
            $rsps['data'] = $goods_data;
            $rsps['count_goods_price'] = $count_goods_price_all;//总购买价
            $rsps['count_return_money'] = $count_return_money_all;//总返现
            $rsps['total'] = $total_all;
            $rsps['goods_freight'] = $goods_freight_all;
            $rsps['msg'] = "获取成功";
            return $rsps;
        } else {
            $attribute_ids = $goods_attribute_ids[0];
            $goods_id = $goods_ids[0];
            $goods_number = $goods_id_number[$goods_id . "_" . $attribute_ids];
            $goods = $goods_common_model->getCommonAttrId($attribute_ids, $field);
            if (empty($goods)) {
                $rsps['code'] = 0;
                $rsps['msg'] = "商品不存在";
                return $rsps;
            }
            if (empty($goods_number)) {
                $goods_number = 1;
            }
            if (intval($goods_number) > intval($goods['goods_storage'])) {
                $goods_storage = AgencyGoodsModel::getStore($agency_id, $goods['id']);
                if (intval($goods_number) > intval($goods_storage)) {
                    $rsps['code'] = 0;
                    $rsps['data'] = $goods['id'];
                    $rsps['msg'] = "商品库存不足";
                    return $rsps;
                } else {
                    $goods['goods_storage'] = $goods_storage;
                }
            }
            if ($member_level == 0) {
                $goods['goods_return_money'] = 0;
            }
            $freight_data = GoodsFreightModel::getFreight($goods['freight_id']);
            $base_freight = $freight_data['base_freight'];
            $count_goods_price = floatval($goods['goods_sell_price']) * $goods_number;//总购买价
            $count_return_money = floatval($goods['goods_return_money']) * $goods_number;//总返现
            $store_model = new StoreModel();
            $store = $store_model->getStoreInfo($goods['store_id'], 'id,store_name,store_label');
            $goods_data[$goods['store_id']]['store'] = $store;
            //利润
            $profit = floatval($goods['goods_sell_price']) - floatval($goods['goods_cost_price']);
            $cost_price = floatval($goods['goods_cost_price']) * intval($goods_number);
            $goods_data[$goods['store_id']]['list'][] = [
                'goods_id' => $goods['goods_id'],
                'goods_title' => $goods['goods_title'],
                'attribute_names' => $goods['attribute_names'],
                'attribute_ids' => $goods['attribute_ids'],
                'distributor_id' => $goods['distributor_id'],
                'attribute_ids_show' => strpos($goods['attribute_ids'], '_') > 0,
                'goods_img' => $goods['goods_img'],
                'goods_photo' => $goods['goods_photo'],
                'goods_special' => $goods['goods_special'],
                'platform_price' => $goods['goods_sell_price'],
                'goods_price' => $goods['goods_sell_price'],
                'cost_price' => $goods['goods_cost_price'],
                'agency_price' => $goods['goods_agency_price'],
                'agency_money' => $goods['goods_return_agency_money'] * $profit,
                'return_money' => $goods['goods_return_money'] * $profit,
                'agency_profit_money' => floatval($goods['goods_sell_price']) - floatval($goods['goods_agency_price']),
                'top_money' => $goods['goods_top_money'] * $profit,
                'top_top_money' => $goods['goods_top_top_money'] * $profit,
                'channel_money' => $goods['goods_ratio_price'],
                'goods_storage' => $goods['goods_storage'],
                'goods_number' => $goods_number,
                'channel' => $channel
            ];
            $total = floatval($goods['goods_sell_price']) * intval($goods_number);
            $goods_freight = intval($goods_number) * floatval($freight_data['one_freight']);
            if ($goods_freight >= 0) {
                $goods_freight += $base_freight;
            }
            $keyword = $goods['goods_title'];
            $goods_data[$goods['store_id']]['basic'] = [
                'goods_freight' => $goods_freight,
                'total' => $total,
                'keyword' => $keyword,
                'cost_price' => $cost_price,
                'count_return_money' => $count_return_money,
                'count_goods_price' => $count_goods_price,
            ];
            $rsps['code'] = 1;
            $rsps['data'] = $goods_data;
            $rsps['count_goods_price'] = $count_goods_price;//总购买价
            $rsps['count_return_money'] = $count_return_money;//总返现
            $rsps['goods_freight'] = $goods_freight;
            $rsps['total'] = $total;
            $rsps['msg'] = "获取成功";
            return $rsps;
        }
    }

}
